package com.whz.mutithread;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;

/**
 * @ClassName CountDownLatchDemo
 * @Description TODO 使用CountDownLatch完成
 * @Author hongzhi
 * @Date 2021/5/26 14:25
 * @Version 1.0
 */
public class CountDownLatchDemo {
    /**
     * 用来给一个动作的并发执行定时。
     * 这个框架中只包含单个方法
     * 该方法带有一个执行该动作的 executor 一个并发级别 表示该动作的 runnable
     * 所有的工作线程自身都准备好，要在timer现车给启动时钟之前完成该动作，以及表示该动作的runnable
     * 所有工作线程都准备好运行该动作时,timer线程就"发起头炮",同时允许工作线程执行该动作
     * 一旦最后一个工作线程完成该动作,timer线程就立即停止计时
     * @param executor
     * @param concurrency 表示要并发执行该动作的次数
     * @param action
     * @return
     */
    public static long time(Executor executor, int concurrency,
                            Runnable action) throws InterruptedException {
        /*工作线程用它来告诉timer线程它们已经准备好了*/
        CountDownLatch ready = new CountDownLatch(concurrency);
        CountDownLatch start = new CountDownLatch(1);
        CountDownLatch done = new CountDownLatch(concurrency);

        for (int i = 0; i < concurrency; i++) {
            executor.execute(() -> {
                ready.countDown();
                try {
                    start.await();
                    action.run();
                } catch (InterruptedException e) {
                    Thread.currentThread();
                } finally {
                    done.countDown();
                }
            });
        }
        ready.await();
        long startNanos = System.nanoTime();
        start.countDown();
        done.await();
        return System.nanoTime() - startNanos;

    }
}
